#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
媒体预览编辑模块
提供视频和音频文件的预览和基本编辑功能
"""

import os
import sys
import tempfile
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from pathlib import Path
from PyQt6.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, 
    QSlider, QSpinBox, QGroupBox, QGridLayout, QComboBox,
    QTextEdit, QMessageBox, QProgressBar, QFrame, QSplitter,
    QWidget, QTabWidget, QCheckBox, QDoubleSpinBox, QFileDialog,
    QScrollArea
)
from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer, QUrl
from PyQt6.QtGui import QFont, QPixmap
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtMultimediaWidgets import QVideoWidget

# 设置matplotlib后端
matplotlib.use('Agg')

try:
    import ffmpeg
except ImportError:
    ffmpeg = None

try:
    from PIL import Image
except ImportError:
    Image = None

try:
    import librosa
except ImportError:
    librosa = None


class WaveformThread(QThread):
    """音频波形图生成线程"""
    waveform_ready = pyqtSignal(str)  # 发送波形图文件路径
    error_occurred = pyqtSignal(str)
    
    def __init__(self, file_path):
        super().__init__()
        self.file_path = file_path
    
    def run(self):
        try:
            if not librosa:
                self.error_occurred.emit("缺少librosa库，无法生成波形图")
                return
            
            # 加载完整音频文件（不限制时长）
            y, sr = librosa.load(self.file_path)
            
            # 计算总时长
            duration = len(y) / sr
            
            # 创建更宽的波形图以支持滚动
            # 根据音频时长动态调整图片宽度，每分钟约10英寸
            width = max(12, duration / 60 * 10)
            plt.figure(figsize=(width, 6))
            plt.style.use('dark_background')
            
            # 设置中文字体
            try:
                # 尝试设置中文字体
                plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial Unicode MS', 'DejaVu Sans']
                plt.rcParams['axes.unicode_minus'] = False
            except:
                # 如果中文字体设置失败，使用英文标签
                pass
            
            # 计算时间轴
            time = np.linspace(0, duration, len(y))
            
            # 绘制波形
            plt.plot(time, y, color='#00ff88', linewidth=0.3, alpha=0.8)
            plt.fill_between(time, y, alpha=0.3, color='#00ff88')
            
            # 设置图表样式（支持中英文）
            try:
                plt.title('音频波形图', color='white', fontsize=16, pad=20)
                plt.xlabel('时间', color='white', fontsize=12)
                plt.ylabel('振幅', color='white', fontsize=12)
            except:
                # 如果中文显示有问题，使用英文
                plt.title('Audio Waveform', color='white', fontsize=16, pad=20)
                plt.xlabel('Time', color='white', fontsize=12)
                plt.ylabel('Amplitude', color='white', fontsize=12)
            plt.grid(True, alpha=0.3)
            
            # 设置时间轴格式为分钟:秒
            def format_time(x, pos):
                minutes = int(x // 60)
                seconds = int(x % 60)
                return f'{minutes}:{seconds:02d}'
            
            from matplotlib.ticker import FuncFormatter
            plt.gca().xaxis.set_major_formatter(FuncFormatter(format_time))
            
            # 设置时间轴刻度间隔
            if duration <= 300:  # 5分钟以内，每30秒一个刻度
                interval = 30
            elif duration <= 1800:  # 30分钟以内，每2分钟一个刻度
                interval = 120
            else:  # 超过30分钟，每5分钟一个刻度
                interval = 300
            
            plt.xticks(np.arange(0, duration + interval, interval))
            
            # 设置背景色
            plt.gca().set_facecolor('#2b2b2b')
            plt.gcf().patch.set_facecolor('#2b2b2b')
            
            # 调整布局
            plt.tight_layout()
            
            # 保存到临时文件，使用更高的DPI以支持缩放
            temp_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
            plt.savefig(temp_file.name, dpi=150, bbox_inches='tight', 
                       facecolor='#2b2b2b', edgecolor='none')
            plt.close()
            
            self.waveform_ready.emit(temp_file.name)
            
        except Exception as e:
            self.error_occurred.emit(f"生成波形图失败: {str(e)}")


class MediaInfoThread(QThread):
    """媒体信息获取线程"""
    info_ready = pyqtSignal(dict)
    error_occurred = pyqtSignal(str)
    
    def __init__(self, file_path):
        super().__init__()
        self.file_path = file_path
    
    def run(self):
        try:
            if ffmpeg:
                # 使用ffprobe获取媒体信息
                probe = ffmpeg.probe(self.file_path)
                
                info = {
                    'format': probe.get('format', {}),
                    'streams': probe.get('streams', []),
                    'duration': float(probe['format'].get('duration', 0)),
                    'size': int(probe['format'].get('size', 0)),
                    'bitrate': int(probe['format'].get('bit_rate', 0))
                }
                
                # 分析视频和音频流
                video_streams = [s for s in info['streams'] if s['codec_type'] == 'video']
                audio_streams = [s for s in info['streams'] if s['codec_type'] == 'audio']
                
                if video_streams:
                    video = video_streams[0]
                    info['video'] = {
                        'codec': video.get('codec_name', 'unknown'),
                        'width': int(video.get('width', 0)),
                        'height': int(video.get('height', 0)),
                        'fps': eval(video.get('r_frame_rate', '0/1')),
                        'bitrate': int(video.get('bit_rate', 0))
                    }
                
                if audio_streams:
                    audio = audio_streams[0]
                    info['audio'] = {
                        'codec': audio.get('codec_name', 'unknown'),
                        'sample_rate': int(audio.get('sample_rate', 0)),
                        'channels': int(audio.get('channels', 0)),
                        'bitrate': int(audio.get('bit_rate', 0))
                    }
                
                self.info_ready.emit(info)
            else:
                self.error_occurred.emit("缺少ffmpeg-python库")
        except Exception as e:
            self.error_occurred.emit(f"获取媒体信息失败: {str(e)}")


class MediaPreviewDialog(QDialog):
    """媒体预览编辑对话框"""
    
    def __init__(self, file_path, parent=None):
        super().__init__(parent)
        self.file_path = file_path
        self.media_info = {}
        self.is_video = self._is_video_file(file_path)
        self.is_audio = self._is_audio_file(file_path)
        self.waveform_image_path = None
        
        self.setWindowTitle(f"媒体预览编辑 - {Path(file_path).name}")
        self.setGeometry(100, 100, 1000, 700)
        
        self.init_ui()
        self.setup_media_player()
        self.load_media_info()
        
        # 如果是音频文件，生成波形图
        if self.is_audio:
            self.load_waveform()
        
    def _is_video_file(self, file_path):
        """检查是否为视频文件"""
        video_extensions = {'.mp4', '.mkv', '.avi', '.mov', '.webm', '.flv', '.wmv'}
        return Path(file_path).suffix.lower() in video_extensions
    
    def _is_audio_file(self, file_path):
        """检查是否为音频文件"""
        audio_extensions = {'.mp3', '.wav', '.flac', '.aac', '.m4a', '.ogg', '.wma'}
        return Path(file_path).suffix.lower() in audio_extensions
    
    def init_ui(self):
        """初始化用户界面"""
        layout = QVBoxLayout(self)
        
        # 创建分割器
        splitter = QSplitter(Qt.Orientation.Horizontal)
        layout.addWidget(splitter)
        
        # 左侧：预览区域
        preview_widget = self.create_preview_widget()
        splitter.addWidget(preview_widget)
        
        # 右侧：编辑控制区域
        control_widget = self.create_control_widget()
        splitter.addWidget(control_widget)
        
        # 设置分割器比例
        splitter.setSizes([600, 400])
        
        # 底部按钮
        button_layout = QHBoxLayout()
        
        self.export_btn = QPushButton("导出编辑")
        self.export_btn.clicked.connect(self.export_edited_media)
        self.export_btn.setEnabled(False)
        
        self.close_btn = QPushButton("关闭")
        self.close_btn.clicked.connect(self.close)
        
        button_layout.addStretch()
        button_layout.addWidget(self.export_btn)
        button_layout.addWidget(self.close_btn)
        
        layout.addLayout(button_layout)
    
    def create_preview_widget(self):
        """创建预览区域"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 媒体播放器区域
        if self.is_video:
            self.video_widget = QVideoWidget()
            self.video_widget.setMinimumSize(400, 300)
            layout.addWidget(self.video_widget)
        else:
            # 音频文件显示波形图（使用滚动区域）
            self.audio_scroll = QScrollArea()
            self.audio_scroll.setMinimumSize(400, 300)
            self.audio_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
            self.audio_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
            self.audio_scroll.setWidgetResizable(False)  # 不自动调整内容大小
            
            # 创建显示波形图的标签
            self.audio_display = QLabel("正在生成波形图...")
            self.audio_display.setAlignment(Qt.AlignmentFlag.AlignCenter)
            self.audio_display.setMinimumSize(400, 300)
            self.audio_display.setStyleSheet("""
                QLabel {
                    border: 2px solid #cccccc;
                    border-radius: 5px;
                    background-color: #2b2b2b;
                    font-size: 16px;
                    color: #ffffff;
                }
            """)
            
            # 将标签放入滚动区域
            self.audio_scroll.setWidget(self.audio_display)
            self.audio_scroll.setStyleSheet("""
                QScrollArea {
                    border: 2px solid #cccccc;
                    border-radius: 5px;
                    background-color: #2b2b2b;
                }
            """)
            
            layout.addWidget(self.audio_scroll)
        
        # 播放控制
        control_layout = QHBoxLayout()
        
        self.play_btn = QPushButton("播放")
        self.play_btn.clicked.connect(self.toggle_playback)
        control_layout.addWidget(self.play_btn)
        
        self.stop_btn = QPushButton("停止")
        self.stop_btn.clicked.connect(self.stop_playback)
        control_layout.addWidget(self.stop_btn)
        
        # 进度条
        self.position_slider = QSlider(Qt.Orientation.Horizontal)
        self.position_slider.sliderMoved.connect(self.set_position)
        control_layout.addWidget(self.position_slider)
        
        # 时间显示
        self.time_label = QLabel("00:00 / 00:00")
        control_layout.addWidget(self.time_label)
        
        layout.addLayout(control_layout)
        
        return widget
    
    def create_control_widget(self):
        """创建控制区域"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 创建标签页
        tab_widget = QTabWidget()
        
        # 媒体信息标签页
        info_tab = self.create_info_tab()
        tab_widget.addTab(info_tab, "媒体信息")
        
        # 编辑选项标签页
        edit_tab = self.create_edit_tab()
        tab_widget.addTab(edit_tab, "编辑选项")
        
        # 输出设置标签页
        output_tab = self.create_output_tab()
        tab_widget.addTab(output_tab, "输出设置")
        
        layout.addWidget(tab_widget)
        
        return widget
    
    def create_info_tab(self):
        """创建媒体信息标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 基本信息
        info_group = QGroupBox("基本信息")
        info_layout = QGridLayout(info_group)
        
        self.file_name_label = QLabel(Path(self.file_path).name)
        self.file_size_label = QLabel("计算中...")
        self.duration_label = QLabel("计算中...")
        self.format_label = QLabel("计算中...")
        
        info_layout.addWidget(QLabel("文件名:"), 0, 0)
        info_layout.addWidget(self.file_name_label, 0, 1)
        info_layout.addWidget(QLabel("文件大小:"), 1, 0)
        info_layout.addWidget(self.file_size_label, 1, 1)
        info_layout.addWidget(QLabel("时长:"), 2, 0)
        info_layout.addWidget(self.duration_label, 2, 1)
        info_layout.addWidget(QLabel("格式:"), 3, 0)
        info_layout.addWidget(self.format_label, 3, 1)
        
        layout.addWidget(info_group)
        
        # 详细信息文本区域
        details_group = QGroupBox("详细信息")
        details_layout = QVBoxLayout(details_group)
        
        self.details_text = QTextEdit()
        self.details_text.setReadOnly(True)
        self.details_text.setMaximumHeight(200)
        details_layout.addWidget(self.details_text)
        
        layout.addWidget(details_group)
        layout.addStretch()
        
        return widget
    
    def create_edit_tab(self):
        """创建编辑选项标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 时间裁剪
        trim_group = QGroupBox("时间裁剪")
        trim_layout = QGridLayout(trim_group)
        
        self.trim_enabled = QCheckBox("启用时间裁剪")
        self.trim_enabled.stateChanged.connect(self.on_trim_enabled_changed)
        trim_layout.addWidget(self.trim_enabled, 0, 0, 1, 2)
        
        trim_layout.addWidget(QLabel("开始时间 (秒):"), 1, 0)
        self.start_time_spin = QDoubleSpinBox()
        self.start_time_spin.setMinimum(0)
        self.start_time_spin.setMaximum(3600)
        self.start_time_spin.setDecimals(2)
        self.start_time_spin.setEnabled(False)
        trim_layout.addWidget(self.start_time_spin, 1, 1)
        
        trim_layout.addWidget(QLabel("结束时间 (秒):"), 2, 0)
        self.end_time_spin = QDoubleSpinBox()
        self.end_time_spin.setMinimum(0)
        self.end_time_spin.setMaximum(3600)
        self.end_time_spin.setDecimals(2)
        self.end_time_spin.setEnabled(False)
        trim_layout.addWidget(self.end_time_spin, 2, 1)
        
        layout.addWidget(trim_group)
        
        if self.is_video:
            # 视频特定选项
            video_group = QGroupBox("视频选项")
            video_layout = QGridLayout(video_group)
            
            # 分辨率调整
            self.resize_enabled = QCheckBox("调整分辨率")
            self.resize_enabled.stateChanged.connect(self.on_resize_enabled_changed)
            video_layout.addWidget(self.resize_enabled, 0, 0, 1, 2)
            
            video_layout.addWidget(QLabel("宽度:"), 1, 0)
            self.width_spin = QSpinBox()
            self.width_spin.setMinimum(1)
            self.width_spin.setMaximum(7680)
            self.width_spin.setValue(1920)
            self.width_spin.setEnabled(False)
            video_layout.addWidget(self.width_spin, 1, 1)
            
            video_layout.addWidget(QLabel("高度:"), 2, 0)
            self.height_spin = QSpinBox()
            self.height_spin.setMinimum(1)
            self.height_spin.setMaximum(4320)
            self.height_spin.setValue(1080)
            self.height_spin.setEnabled(False)
            video_layout.addWidget(self.height_spin, 2, 1)
            
            # 帧率调整
            self.fps_enabled = QCheckBox("调整帧率")
            self.fps_enabled.stateChanged.connect(self.on_fps_enabled_changed)
            video_layout.addWidget(self.fps_enabled, 3, 0, 1, 2)
            
            video_layout.addWidget(QLabel("帧率 (fps):"), 4, 0)
            self.fps_spin = QDoubleSpinBox()
            self.fps_spin.setMinimum(1)
            self.fps_spin.setMaximum(120)
            self.fps_spin.setValue(30)
            self.fps_spin.setDecimals(2)
            self.fps_spin.setEnabled(False)
            video_layout.addWidget(self.fps_spin, 4, 1)
            
            layout.addWidget(video_group)
        
        if self.is_audio or self.is_video:
            # 音频选项
            audio_group = QGroupBox("音频选项")
            audio_layout = QGridLayout(audio_group)
            
            # 音量调整
            self.volume_enabled = QCheckBox("调整音量")
            self.volume_enabled.stateChanged.connect(self.on_volume_enabled_changed)
            audio_layout.addWidget(self.volume_enabled, 0, 0, 1, 2)
            
            audio_layout.addWidget(QLabel("音量 (%):"), 1, 0)
            self.volume_spin = QSpinBox()
            self.volume_spin.setMinimum(0)
            self.volume_spin.setMaximum(200)
            self.volume_spin.setValue(100)
            self.volume_spin.setEnabled(False)
            audio_layout.addWidget(self.volume_spin, 1, 1)
            
            layout.addWidget(audio_group)
        
        layout.addStretch()
        return widget
    
    def create_output_tab(self):
        """创建输出设置标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 输出格式
        format_group = QGroupBox("输出格式")
        format_layout = QGridLayout(format_group)
        
        format_layout.addWidget(QLabel("输出格式:"), 0, 0)
        self.output_format_combo = QComboBox()
        
        if self.is_video:
            self.output_format_combo.addItems(["MP4", "MKV", "AVI", "MOV", "WebM"])
        elif self.is_audio:
            self.output_format_combo.addItems(["MP3", "WAV", "FLAC", "AAC", "OGG"])
        
        format_layout.addWidget(self.output_format_combo, 0, 1)
        
        # 质量设置
        format_layout.addWidget(QLabel("质量:"), 1, 0)
        self.quality_combo = QComboBox()
        self.quality_combo.addItems(["高质量", "中等质量", "低质量", "自定义"])
        format_layout.addWidget(self.quality_combo, 1, 1)
        
        layout.addWidget(format_group)
        
        # 进度显示
        self.export_progress = QProgressBar()
        self.export_progress.setVisible(False)
        layout.addWidget(self.export_progress)
        
        layout.addStretch()
        return widget
    
    def setup_media_player(self):
        """设置媒体播放器"""
        self.media_player = QMediaPlayer()
        self.audio_output = QAudioOutput()
        self.media_player.setAudioOutput(self.audio_output)
        
        if self.is_video:
            self.media_player.setVideoOutput(self.video_widget)
        
        # 连接信号
        self.media_player.positionChanged.connect(self.position_changed)
        self.media_player.durationChanged.connect(self.duration_changed)
        self.media_player.playbackStateChanged.connect(self.playback_state_changed)
        
        # 加载媒体文件
        self.media_player.setSource(QUrl.fromLocalFile(self.file_path))
    
    def load_media_info(self):
        """加载媒体信息"""
        self.info_thread = MediaInfoThread(self.file_path)
        self.info_thread.info_ready.connect(self.update_media_info)
        self.info_thread.error_occurred.connect(self.show_info_error)
        self.info_thread.start()
    
    def load_waveform(self):
        """加载音频波形图"""
        self.waveform_thread = WaveformThread(self.file_path)
        self.waveform_thread.waveform_ready.connect(self.update_waveform_display)
        self.waveform_thread.error_occurred.connect(self.show_waveform_error)
        self.waveform_thread.start()
    
    def update_waveform_display(self, image_path):
        """更新波形图显示"""
        self.waveform_image_path = image_path
        pixmap = QPixmap(image_path)
        if not pixmap.isNull():
            # 设置标签大小为图片的实际大小，以支持滚动
            self.audio_display.setPixmap(pixmap)
            self.audio_display.resize(pixmap.size())
            self.audio_display.setScaledContents(False)  # 不缩放内容
            
            # 确保滚动区域能够正确显示内容
            self.audio_scroll.setWidgetResizable(False)
        else:
            self.audio_display.setText("波形图加载失败")
            self.audio_display.setMinimumSize(400, 300)
    
    def show_waveform_error(self, error_msg):
        """显示波形图生成错误"""
        self.audio_display.setText(f"波形图生成失败:\n{error_msg}")
        self.audio_display.setStyleSheet("""
            QLabel {
                border: 2px solid #cccccc;
                border-radius: 5px;
                background-color: #2b2b2b;
                font-size: 12px;
                color: #ff6666;
                padding: 10px;
            }
        """)
    
    def update_media_info(self, info):
        """更新媒体信息显示"""
        self.media_info = info
        
        # 更新基本信息
        file_size = info.get('size', 0)
        if file_size > 0:
            size_mb = file_size / (1024 * 1024)
            self.file_size_label.setText(f"{size_mb:.2f} MB")
        
        duration = info.get('duration', 0)
        if duration > 0:
            minutes = int(duration // 60)
            seconds = int(duration % 60)
            self.duration_label.setText(f"{minutes:02d}:{seconds:02d}")
            
            # 设置时间裁剪的最大值
            self.end_time_spin.setMaximum(duration)
            self.end_time_spin.setValue(duration)
        
        format_info = info.get('format', {})
        self.format_label.setText(format_info.get('format_name', '未知'))
        
        # 更新详细信息
        details = []
        details.append(f"文件路径: {self.file_path}")
        details.append(f"格式: {format_info.get('format_name', '未知')}")
        details.append(f"时长: {duration:.2f} 秒")
        details.append(f"比特率: {info.get('bitrate', 0)} bps")
        
        if 'video' in info:
            video = info['video']
            details.append(f"\n视频信息:")
            details.append(f"  编解码器: {video.get('codec', '未知')}")
            details.append(f"  分辨率: {video.get('width', 0)}x{video.get('height', 0)}")
            details.append(f"  帧率: {video.get('fps', 0):.2f} fps")
            details.append(f"  比特率: {video.get('bitrate', 0)} bps")
            
            # 设置分辨率默认值
            self.width_spin.setValue(video.get('width', 1920))
            self.height_spin.setValue(video.get('height', 1080))
            self.fps_spin.setValue(video.get('fps', 30))
        
        if 'audio' in info:
            audio = info['audio']
            details.append(f"\n音频信息:")
            details.append(f"  编解码器: {audio.get('codec', '未知')}")
            details.append(f"  采样率: {audio.get('sample_rate', 0)} Hz")
            details.append(f"  声道数: {audio.get('channels', 0)}")
            details.append(f"  比特率: {audio.get('bitrate', 0)} bps")
        
        self.details_text.setPlainText('\n'.join(details))
    
    def show_info_error(self, error_msg):
        """显示信息获取错误"""
        self.details_text.setPlainText(f"获取媒体信息失败: {error_msg}")
    
    # 播放控制方法
    def toggle_playback(self):
        """切换播放/暂停"""
        if self.media_player.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
            self.media_player.pause()
        else:
            self.media_player.play()
    
    def stop_playback(self):
        """停止播放"""
        self.media_player.stop()
    
    def set_position(self, position):
        """设置播放位置"""
        self.media_player.setPosition(position)
    
    def position_changed(self, position):
        """播放位置改变"""
        self.position_slider.setValue(position)
        
        # 更新时间显示
        current_time = position // 1000
        total_time = self.media_player.duration() // 1000
        
        current_min = current_time // 60
        current_sec = current_time % 60
        total_min = total_time // 60
        total_sec = total_time % 60
        
        self.time_label.setText(f"{current_min:02d}:{current_sec:02d} / {total_min:02d}:{total_sec:02d}")
    
    def duration_changed(self, duration):
        """播放时长改变"""
        self.position_slider.setRange(0, duration)
    
    def playback_state_changed(self, state):
        """播放状态改变"""
        if state == QMediaPlayer.PlaybackState.PlayingState:
            self.play_btn.setText("暂停")
        else:
            self.play_btn.setText("播放")
    
    # 编辑选项事件处理
    def on_trim_enabled_changed(self, state):
        """时间裁剪启用状态改变"""
        enabled = state == Qt.CheckState.Checked.value
        self.start_time_spin.setEnabled(enabled)
        self.end_time_spin.setEnabled(enabled)
        self.update_export_button()
    
    def on_resize_enabled_changed(self, state):
        """分辨率调整启用状态改变"""
        enabled = state == Qt.CheckState.Checked.value
        self.width_spin.setEnabled(enabled)
        self.height_spin.setEnabled(enabled)
        self.update_export_button()
    
    def on_fps_enabled_changed(self, state):
        """帧率调整启用状态改变"""
        enabled = state == Qt.CheckState.Checked.value
        self.fps_spin.setEnabled(enabled)
        self.update_export_button()
    
    def on_volume_enabled_changed(self, state):
        """音量调整启用状态改变"""
        enabled = state == Qt.CheckState.Checked.value
        self.volume_spin.setEnabled(enabled)
        self.update_export_button()
    
    def update_export_button(self):
        """更新导出按钮状态"""
        # 检查是否有任何编辑选项被启用
        has_edits = (
            self.trim_enabled.isChecked() or
            (hasattr(self, 'resize_enabled') and self.resize_enabled.isChecked()) or
            (hasattr(self, 'fps_enabled') and self.fps_enabled.isChecked()) or
            (hasattr(self, 'volume_enabled') and self.volume_enabled.isChecked())
        )
        
        self.export_btn.setEnabled(has_edits)
    
    def export_edited_media(self):
        """导出编辑后的媒体文件"""
        if not ffmpeg:
            QMessageBox.warning(self, "错误", "缺少ffmpeg-python库，无法导出")
            return
        
        # 选择输出文件
        output_format = self.output_format_combo.currentText().lower()
        file_filter = f"{output_format.upper()} files (*.{output_format})"
        
        output_file, _ = QFileDialog.getSaveFileName(
            self, "保存编辑后的文件", 
            f"{Path(self.file_path).stem}_edited.{output_format}",
            file_filter
        )
        
        if not output_file:
            return
        
        # 构建ffmpeg命令
        try:
            # 构建输入参数
            input_kwargs = {}
            
            # 时间裁剪参数
            if self.trim_enabled.isChecked():
                start_time = self.start_time_spin.value()
                end_time = self.end_time_spin.value()
                input_kwargs['ss'] = start_time
                input_kwargs['t'] = end_time - start_time
            
            input_stream = ffmpeg.input(self.file_path, **input_kwargs)
            
            # 构建输出参数
            output_kwargs = {}
            
            # 视频处理
            if self.is_video:
                # 视频滤镜链
                video_filters = []
                
                if self.resize_enabled.isChecked():
                    width = self.width_spin.value()
                    height = self.height_spin.value()
                    video_filters.append(f'scale={width}:{height}')
                
                if self.fps_enabled.isChecked():
                    fps = self.fps_spin.value()
                    video_filters.append(f'fps={fps}')
                
                if video_filters:
                    output_kwargs['vf'] = ','.join(video_filters)
                
                # 音频滤镜
                if hasattr(self, 'volume_enabled') and self.volume_enabled.isChecked():
                    volume = self.volume_spin.value() / 100.0
                    output_kwargs['af'] = f'volume={volume}'
                
                # 质量设置
                quality_map = {"高质量": 18, "中等质量": 23, "低质量": 28, "自定义": 23}
                quality_text = self.quality_combo.currentText()
                crf = quality_map.get(quality_text, 23)
                output_kwargs['crf'] = crf
                
            else:
                # 纯音频处理
                if self.volume_enabled.isChecked():
                    volume = self.volume_spin.value() / 100.0
                    output_kwargs['af'] = f'volume={volume}'
            
            # 创建输出流
            output_stream = ffmpeg.output(input_stream, output_file, **output_kwargs)
            
            # 显示进度条
            self.export_progress.setVisible(True)
            self.export_progress.setValue(0)
            self.export_btn.setEnabled(False)
            
            # 执行转换
            ffmpeg.run(output_stream, overwrite_output=True)
            
            # 完成
            self.export_progress.setValue(100)
            QMessageBox.information(self, "成功", f"文件已导出到: {output_file}")
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")
        finally:
            self.export_progress.setVisible(False)
            self.export_btn.setEnabled(True)
            self.update_export_button()
    
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        try:
            # 停止媒体播放
            if hasattr(self, 'media_player') and self.media_player:
                self.media_player.stop()
                # 断开所有信号连接
                self.media_player.positionChanged.disconnect()
                self.media_player.durationChanged.disconnect()
                self.media_player.playbackStateChanged.disconnect()
                # 清理媒体播放器资源
                self.media_player.setSource(QUrl())
                if hasattr(self, 'audio_output') and self.audio_output:
                    self.audio_output.deleteLater()
                self.media_player.deleteLater()
            
            # 停止信息获取线程
            if hasattr(self, 'info_thread') and self.info_thread and self.info_thread.isRunning():
                self.info_thread.quit()
                self.info_thread.wait(1000)  # 等待最多1秒
                if self.info_thread.isRunning():
                    self.info_thread.terminate()
            
            # 停止波形图生成线程
            if hasattr(self, 'waveform_thread') and self.waveform_thread and self.waveform_thread.isRunning():
                self.waveform_thread.quit()
                self.waveform_thread.wait(1000)  # 等待最多1秒
                if self.waveform_thread.isRunning():
                    self.waveform_thread.terminate()
            
            # 清理临时波形图文件
            if hasattr(self, 'waveform_image_path') and self.waveform_image_path:
                try:
                    if os.path.exists(self.waveform_image_path):
                        os.unlink(self.waveform_image_path)
                except Exception:
                    pass  # 忽略清理错误
            
        except Exception as e:
            print(f"关闭窗口时清理资源出错: {e}")
        finally:
            # 接受关闭事件
            event.accept()